using DemoContentLoader;
using DemoRenderer;
using Demos.Demos;
using Demos.Demos.Sponsors;
using System;
using System.Collections.Generic;

namespace Demos
{
    /// <summary>
    /// 根据可用演示集按需构建演示。
    /// </summary>
    public class DemoSet
    {
        struct Option
        {
            public string Name;
            public Func<ContentArchive, Camera, RenderSurface, Demo> Builder;
        }

        List<Option> options = new List<Option>();
        void AddOption<T>() where T : Demo, new()
        {
            options.Add(new Option
            {
                Builder = (content, camera, surface) =>
                {
                    // 请注意,实际工作是在Initialize函数中完成的,而不是在构造函数中完成的。
                    // "new T()"语法实际上使用反射并以一种不方便的方式重新打包异常。
                    // 通过改用Initialize,堆栈跟踪和调试器将直接进入源代码。
                    var demo = new T();
                    //demo.LoadGraphicalContent(content, surface);
                    demo.Initialize(content, camera);
                    return demo;
                },
                Name = typeof(T).Name
            });
        }

        public DemoSet()
        {
            //AddOption<CarDemo>();
            //AddOption<CharacterDemo>();
            //AddOption<TankDemo>();
            //AddOption<ColosseumDemo>();
            AddOption<PyramidDemo>();
            AddOption<RagdollDemo>();
            AddOption<ContinuousCollisionDetectionDemo>();
            AddOption<ClothDemo>();
            AddOption<NewtDemo>();
            AddOption<PlanetDemo>();
            AddOption<CompoundTestDemo>();
            AddOption<BlockChainDemo>();
            AddOption<RayCastingDemo>();
            AddOption<SweepDemo>();
            AddOption<ContactEventsDemo>();
            AddOption<SolverContactEnumerationDemo>();
            AddOption<CustomVoxelCollidableDemo>();
            AddOption<RopeStabilityDemo>();
            AddOption<SubsteppingDemo>();
            AddOption<SponsorDemo>();
        }

        public int Count { get { return options.Count; } }

        public string GetName(int index)
        {
            return options[index].Name;
        }

        public Demo Build(int index, ContentArchive content, Camera camera, RenderSurface surface)
        {
            return options[index].Builder(content, camera, surface);
        }
    }
}
